//*************************************************************
// led.c
// http://www.upwinder.com/www/66/226.html
// http://www.ece.ust.hk/course/elec254/Project/S2008/GP12/code.htm
// http://recherche.ircam.fr/equipes/analyse-synthese/peeters/ARTICLES/Peeters_2005_ICMC_Tempo.pdf
// with reference to http://hi.baidu.com/lovelink/blog/item/5819c90008dea910738b6522.html
// with reference to http://fourier.eng.hmc.edu/e161/lectures/wht/node2.html
//*************************************************************

#include <avr/io.h>
#include "LED.h"

// light led pattern
unsigned char pidle[8] = {0,0,0,0,0,0,0,0};
unsigned char pplay[8] = {0,0,0,0,0,0,0,0};
unsigned char OFF_LIGHT = 0;
// counter for light display index
unsigned char *cnt;
// reorder sequence for FWT reorder
unsigned char Reorder[16] =  {0,15,7,8,3,12,4,11,1,14,6,9,2,13,5,10};
uint16 data[WINDOW];




void LED_ini(){
//	DDRF		// read from ADC
//	DDRA		// read from source A
//	ADMUX		// ADMUX[3..0]
//	timer0
}







// function of led light called by timer interupt
void idlelight(unsigned char * cnt){
	//clear timer interupt flag
	//light led
	LED = pidle[*cnt];
	(*cnt)+=1;
	//config timer
	//delay
}
// function of led light called after one count of calbeat
void playlight(unsigned char * cnt){
	//clear timer interupt flag
	//light led
	LED = pplay[*cnt];
	(*cnt)+=1;
	//config timer
	//delay
}
// off all led
void offlight(void){
	LED = OFF_LIGHT;
	//delay
}







void calbeat(uint16 *data, uint8 *cnt){

//--------------process data array use fast walsh transform------------
//recursively separate array[0:x-1]=> sub0=array[0:x/2-1] and sub1=array[(x/2 : x-1 ]
//sub0[i]= sub0[i]+ sub1[i]; sub1[i]=sub1[i]-sub0[i]
//recursive process subarray
//----------------------------------------------------------------------


uint8 ele_sub = WINDOW;				// #elements of subarrays
uint8 hele_sub = (ele_sub/2);		// #half of elements
uint8 num_sub = 1;					// number of subarrays

uint8 i,j;
uint8  index1;	uint8  index2;
uint16 temp1;	uint16 temp2;

uint8 degree = DEGREE;				// we process 16 datas, so WINDOW = 16, DEGREE = 4
uint8 sub_start = 0;


while(degree--){
	sub_start = 0;
	for(i=0; i<num_sub; i++){
		for(j= 0;j<hele_sub; j++){
			index1 = sub_start + j;		index2 = index1 + hele_sub;
			temp1 = data[index1];		temp2 = data[index2];
			data[index1] = temp1 + temp2;
			data[index2] = temp1 - temp2;
		}
		sub_start += ele_sub;
	}
	num_sub<<=1;
	ele_sub>>=1;	hele_sub>>=1;
}

//------------extract frequency---------------------------------------
// reorder the data according to the frequency sequency
// Reorder[16] =  {0 15 7 8 3 12 4 11 1 14 6 9 2 13 5 10}
//--------------------------------------------------------------------

//reorder
uint16 temp[WINDOW];

for(i =0; i<WINDOW; i++)
	temp[Reorder[i]] = data[i];

for(i =0; i<WINDOW; i++)
	data[i] = temp[i];


//compute frequency component, throw away data[0], and add merge intervals to one component
uint16 freq[WINDOW/2];
for(i=0; i<(WINDOW/2); i++)
	freq[i] = temp[i<<1]+ temp[(i<<1)+1];


//--------------------light led matrix-------------------------------
// for the first three freq component, if larger than threshold light
//--------------------------------------------------------------------
if((freq[0]>threshold)||(freq[1]>threshold)||(freq[2]>threshold))
	playlight(cnt);
else offlight();


}







// called at timer0 interrupt, sample frequency is 2kHz, so 0.5ms as period
void sample(uint16 * data, uint8 * index){
	//call ADC converter, get 8bit data
	//append data to the array
	//if full, do dct, else return

	data[*index] = PINF;
	index++;
	if (*index == 16){
		calbeat(data, cnt);
		*index = 0;
	}
}
